<template>
  <view class="uni-select">
    <view class="select-display" @click="togglePopup">
      <text v-if="selectedLabels.length">{{ selectedLabels.join(', ') }}</text>
      <text v-else class="placeholder">{{ placeholder }}</text>
      <text
        v-if="clearable && hasValue"
        class="clear-icon"
        @click.stop="clearSelection"
      >&#10005;</text>
      <text v-else class="arrow">&#9662;</text>
    </view>

    <transition name="fade-slide">
      <view v-if="popupVisible" class="select-popup">
        <scroll-view scroll-y class="popup-scroll">
          <template v-if="options.length">
            <view
              v-for="item in options"
              :key="item.value"
              class="popup-option"
              :class="{ active: isSelected(item) }"
              @click="selectOption(item)">
              <slot name="option" :item="item">
                {{ item.label }}
              </slot>
            </view>
          </template>
          <template v-else>
            <view class="popup-option disabled">
              <slot name="empty">暂无数据</slot>
            </view>
          </template>
        </scroll-view>
      </view>
    </transition>

    
  </view>
</template>

<script>
export default {
  name: 'UniSelect',
  props: {
    value: [String, Number, Array], // v-model
    options: {
      type: Array,
      default: () => [],
    },
    placeholder: {
      type: String,
      default: '請選擇',
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    clearable: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      popupVisible: false,
    }
  },
  computed: {
    selectedLabels() {
      if (this.multiple) {
        return this.options
          .filter(opt => this.value?.includes(opt.value))
          .map(opt => opt.label)
      } else {
        const found = this.options.find(opt => opt.value === this.value)
        return found ? [found.label] : []
      }
    },
    hasValue() {
      return this.multiple ? Array.isArray(this.value) && this.value.length > 0 : !!this.value
    }
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside)
  },
  beforeDestroy() {
    document.removeEventListener('click', this.handleClickOutside)
  },
  methods: {
    togglePopup() {
      this.popupVisible = !this.popupVisible
    },
    handleClickOutside(event) {
      const el = this.$el
      if (el && !el.contains(event.target)) {
        this.popupVisible = false
      }
    },
    isSelected(item) {
      return this.multiple ? this.value?.includes(item.value) : this.value === item.value
    },
    selectOption(item) {
      if (this.multiple) {
        let newValue = Array.isArray(this.value) ? [...this.value] : []
        const idx = newValue.indexOf(item.value)
        if (idx > -1) {
          newValue.splice(idx, 1)
        } else {
          newValue.push(item.value)
        }
        this.$emit('input', newValue)
        this.$emit('change', newValue)
      } else {
        this.$emit('input', item.value)
        this.$emit('change', item.value)
        this.popupVisible = false
      }
    },
    clearSelection() {
      const newValue = this.multiple ? [] : ''
      this.$emit('input', newValue)
      this.$emit('change', newValue)
      this.popupVisible = false
    }
  }
}
</script>

<style scoped>
.uni-select {
  position: relative;
  font-size: 28rpx;
  height: 100%;
}
.select-display {
  height: 100%;
  padding: 10rpx 20rpx;
  border: 1rpx solid #ccc;
  border-radius: 8rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fff;
}
.placeholder {
  color: #ccc;
}
.arrow,
.clear-icon {
  margin-left: 10rpx;
  font-size: 24rpx;
}
.clear-icon {
  color: #999;
}
.select-popup {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  max-height: 800rpx;
  background-color: #fff;
  border: 1rpx solid #ccc;
  z-index: 10;
  border-radius: 8rpx;
}
.popup-scroll {
  max-height: 800rpx;
}
.popup-option {
  padding: 20rpx;
  border-bottom: 1rpx solid #eee;
}
.popup-option:last-child {
  border-bottom: none;
}
.popup-option.active {
  background-color: #f0f9ff;
  color: #007aff;
}
.popup-option.disabled {
  color: #999;
  background-color: #f5f5f5;
}
.popup-option.disabled:active {
  background-color: #f5f5f5;
}
.fade-slide-enter-active,
.fade-slide-leave-active {
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.fade-slide-enter, .fade-slide-leave-to {
  opacity: 0;
  transform: translateY(-10rpx);
}
</style>
